home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1987
/
05
/
joneslst.lst
< prev
next >
Wrap
File List
|
1987-04-10
|
9KB
|
292 lines
Listing One
-- DUNITS.ADA
-- VERSION 1
-- 1 JANUARY 1986
-- DO-WHILE JONES
-- 324 TRACI LANE
-- RIDGECREST, CA 93555
-- (619) 375-4607
package DIMENSIONAL_UNITS is
-- This package provides useful parent types for derived
-- dimensional units. That is, it makes it possible to
-- do this:
-- type Feet is new Integer_Unit;
-- type Radians is new Float_Unit;
-- PI : constant Radians := Type_Convert(3.14159);
-- TARGET_RANGE : Feet;
-- ANGLE : Radians;
-- REVOLUTIONS : integer;
-- These derived data types will inherit all the operations
-- in the package below. These are all the operations which
-- make sense for dimensional quantities.
-- The modulo operation for Float_Units is provided to make
-- it easy to normalize angular measurements.
-- ANGLE := ANGLE mod (2.0 * PI);
-- The division operator for Float_Units which return INTEGERS
-- truncates toward zero (rather than rounding) to make it consistant
-- with integer division, and it lets you do this:
-- REVOLUTIONS := ANGLE / (2.0 * PI);
type Integer_Unit is private;
function Type_Convert(X : integer) return Integer_Unit;
-- Lets you assign values to dimensional objects.
-- For example,
-- TARGET_RANGE := Type_Convert(587);
function "+"(RIGHT : Integer_Unit)
return Integer_Unit;
function "-"(RIGHT : Integer_Unit)
return Integer_Unit;
function "abs"(RIGHT : Integer_Unit)
return Integer_Unit;
function "+"(LEFT, RIGHT : Integer_Unit)
return Integer_Unit;
function "-"(LEFT, RIGHT : Integer_Unit)
return Integer_Unit;
function "*"(LEFT : integer; RIGHT : Integer_Unit)
return Integer_Unit;
function "*"(LEFT : Integer_Unit; RIGHT : integer)
return Integer_Unit;
function "/"(LEFT : Integer_Unit; RIGHT : integer)
return Integer_Unit;
function "/"(LEFT, RIGHT : Integer_Unit)
return integer;
function "/"(LEFT, RIGHT : Integer_Unit)
return float;
function "rem"(LEFT, RIGHT : Integer_Unit)
return Integer_Unit;
function "mod"(LEFT, RIGHT : Integer_Unit)
return Integer_Unit;
function Dimensionless(LEFT : Integer_Unit)
return integer;
function Dimensionless(LEFT : Integer_Unit)
return float;
-- "=" and "/=" are already defined for private types
function "<"(LEFT, RIGHT : Integer_Unit)
return boolean;
function "<="(LEFT, RIGHT : Integer_Unit)
return boolean;
function ">"(LEFT, RIGHT : Integer_Unit)
return boolean;
function ">="(LEFT, RIGHT : Integer_Unit)
return boolean;
type Float_Unit is private;
function Type_Convert(X : float) return Float_Unit;
-- Lets you assign values to dimensional objects.
-- For example,
-- ANGLE := Type_Convert(3.14159);
function "+"(RIGHT : Float_Unit)
return Float_Unit;
function "-"(RIGHT : Float_Unit)
return Float_Unit;
function "abs"(RIGHT : Float_Unit)
return Float_Unit;
function "+"(LEFT, RIGHT : Float_Unit)
return Float_Unit;
function "-"(LEFT, RIGHT : Float_Unit)
return Float_Unit;
function "*"(LEFT : integer; RIGHT : Float_Unit)
return Float_Unit;
function "*"(LEFT : Float_Unit; RIGHT : integer)
return Float_Unit;
function "*"(LEFT : float; RIGHT : Float_Unit)
return Float_Unit;
function "*"(LEFT : Float_Unit; RIGHT : float)
return Float_Unit;
function "/"(LEFT : Float_Unit; RIGHT : integer)
return Float_Unit;
function "/"(LEFT : Float_Unit; RIGHT : float)
return Float_Unit;
function "/"(LEFT, RIGHT : Float_Unit)
return integer; -- trucates toward zero
function "/"(LEFT, RIGHT : Float_Unit)
return float;
function "rem"(LEFT, RIGHT : Float_Unit)
return Float_Unit;
function "mod"(LEFT, RIGHT : Float_Unit)
return Float_Unit;
function Dimensionless(LEFT : Float_Unit)
return integer;
function Dimensionless(LEFT : Float_Unit)
return float;
-- "=" and "/=" are already defined for private types
function "<"(LEFT, RIGHT : Float_Unit)
return boolean;
function "<="(LEFT, RIGHT : Float_Unit)
return boolean;
function ">"(LEFT, RIGHT : Float_Unit)
return boolean;
function ">="(LEFT, RIGHT : Float_Unit)
return boolean;
-- The following don't have any application to dimensional
-- problems. I almost hid them in the package body, but I
-- thought that since I needed them to derive some of the
-- Float_Unit operations someone else might need them, too.
function "/"(LEFT, RIGHT : float) return integer;
-- divide and truncate toward zero
function "rem"(LEFT, RIGHT : float) return float;
function "mod"(LEFT, RIGHT : float) return float;
private
type Integer_Unit is new integer;
type Float_Unit is new float;
end DIMENSIONAL_UNITS;
Listing Two
-- DUEX.ADA
-- This is an example of how the use of dimensional units as data
-- types improves program clarity.
------------------------- Compilation Unit 1 --------------------------
with DIMENSIONAL_UNITS; use DIMENSIONAL_UNITS;
package SPEED_GUN_UNITS is
type Miles_per_hour is new Integer_Unit;
type Hertz is new Float_Unit;
type Miles_per_second is new Float_Unit;
function Type_Convert(X : Miles_per_second)
return Miles_per_hour;
function "*"(LEFT : Miles_per_second; RIGHT : float)
return Miles_per_hour;
end SPEED_GUN_UNITS;
------------------------- Compilation Unit 2 --------------------------
with SPEED_GUN_UNITS; use SPEED_GUN_UNITS;
package HARDWARE_CIRCUITS is
function Xmit_Frequency_Measurement return Hertz;
function Doppler_Frequency_Measurement return Hertz;
procedure put(X : Miles_per_hour);
end HARDWARE_CIRCUITS;
------------------------- Compilation Unit 3 --------------------------
with HARDWARE_CIRCUITS; use HARDWARE_CIRCUITS;
with SPEED_GUN_UNITS; use SPEED_GUN_UNITS;
procedure Speed_Gun is
TRANSMIT_FREQUENCY, DOPPLER_FREQUENCY : Hertz;
SPEED : Miles_per_hour;
C : constant Miles_per_second
:= Type_Convert(186_280.0); -- speed of light
begin
TRANSMIT_FREQUENCY := Xmit_Frequency_Measurement;
DOPPLER_FREQUENCY := Doppler_Frequency_Measurement;
SPEED := (C / 2.0) * (DOPPLER_FREQUENCY / TRANSMIT_FREQUENCY);
put(SPEED);
end Speed_Gun;
------------------------- Compilation Unit 4 --------------------------
package body SPEED_GUN_UNITS is
function Type_Convert(X : Miles_per_second)
return Miles_per_hour is
MPH : Miles_per_second;
begin
MPH := X * 60 * 60;
return Type_Convert(Dimensionless(MPH));
end Type_Convert;
function "*"(LEFT : Miles_per_second; RIGHT : float)
return Miles_per_hour is
begin
return Type_Convert(LEFT * RIGHT);
end "*";
end SPEED_GUN_UNITS;
------------------------- Compilation Unit 5 --------------------------
with TEXT_IO; use TEXT_IO;
package body HARDWARE_CIRCUITS is
-- The statements below are standing in for code which would
-- read the frequency directly from hardware circuits and
-- would display speed on an LCD or LED display. Since I'm
-- using a terminal as a substitute input device I used
-- TEXT_IO to get and put data.
package INT_IO is new INTEGER_IO(integer); use INT_IO;
package F_IO is new FLOAT_IO(float); use F_IO;
function Xmit_Frequency_Measurement return Hertz is
F : float;
begin
put("What is the Transmit Frequency (in Hertz)? ");
get(F);
skip_line; -- TEXT_IO quirk
return Type_Convert(F);
end Xmit_Frequency_Measurement;
function Doppler_Frequency_Measurement return Hertz is
F : float;
begin
put("What is the Doppler Frequency (in Hertz)? ");
get(F);
skip_line; -- TEXT_IO quirk
return Type_Convert(F);
end Doppler_Frequency_Measurement;
procedure put(X : Miles_per_hour) is
I : integer;
begin
I := Dimensionless(X);
put("The speed is "); put(I); put_line(" MPH.");
end put;
end HARDWARE_CIRCUITS;
------------------------- Test Results --------------------------
$ run speed_gun
What is the Transmit Frequency (in Hertz)? 10.0e9
What is the Doppler Frequency (in Hertz)? 1600.0
The speed is 54 MPH.
$
$ run speed_gun
What is the Transmit Frequency (in Hertz)? 10.0e9
What is the Doppler Frequency (in Hertz)? 1000.0
The speed is 34 MPH.
$
$ run speed_gun
What is the Transmit Frequency (in Hertz)? 10.0e9
What is the Doppler Frequency (in Hertz)? 2000.0
The speed is 67 MPH.
$